package cn.tedu.v3_1;

import java.io.*;
import java.net.*;
import java.util.*;

/**
 * Version 3.1 多人聊天室+QQ聊天室
 * 优化空间：代码结构、流没有关闭
 * 代码结构优化：1.包改成通配模式
 *             2.Server端结构
 *             ①传入数据变成静态属性方式---私有化当前类中
 *             优势：2.1静态常量属性，便于开发者维护
 *                  2.2静态常量私有属性，本类任意调取
 *                  2.3Integer使用包装类，获取包装类方法：解析
 *                  自动拆装箱  Integer=6935 == int=6935
 *             ②ClientHandler：多线程：处理多个客户端类
 *              构造器--对象创建--完成三件事情：
 *                    1.确定链接的客户端是谁
 *                    2.确定链接客户端的IP室多少
 *                    3.确定每个客户端都可以进行读写
 *                    4.流作用域：关闭
 */
public class Server {
    private ServerSocket serverSocket;
    //优化：将动态添加值，提升到当前类上，变成私有化属性模式
    private static final  Integer PORT=8764;

    public Server() {
        try {
            serverSocket = new ServerSocket(PORT);
        } catch (BindException e) {
            System.out.println("端口号重复申请，建议换个端口号");
        } catch (IOException e) {
            System.out.println("申请端口号失败...");
        }
    }

    public void start() {
        try {
            while (true) {
                System.out.println("----等待客户端链接----");
                Socket socket = serverSocket.accept();
                System.out.println(socket+"12345");
                String ip = socket.getInetAddress().getHostAddress();
                System.out.println(ip + "客户端链接成功了~~");


                new Thread(new ClientHandler(socket)).start();
            }
        } catch (IOException e) {
            System.out.println("服务器端通讯断开了");
        } finally {
        if(serverSocket!=null&&!serverSocket.isClosed()){
            try {
                serverSocket.close();
            } catch (IOException e) {
                System.out.println("服务器关闭失败");
            }
        }

        }
    }

    public static void main(String[] args) {
        new Server().start();
    }
    //ClientHandler  多线程内部类：处理多个客户端链接
    private class ClientHandler implements Runnable {
    private Socket socket;
    private String ip;
    private BufferedReader br;//3.1输入流：私有化---本类任意调取
                             //赋值  关闭流
    private PrintWriter pw;//3.2输出流：私有化---本类任意调取
        public ClientHandler(Socket s) {
    this.socket = s;//1.确定链接客户端是谁
    ip = socket.getInetAddress().getHostAddress();//2.客户端IP
        //3.确定每个客户端都可以进行读写
        try {
            br = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));
             pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), "UTF8")), true);
        } catch (IOException e) {
            System.out.println("客户端断开通讯");
        }
    }

    public void run() {
    PrintWriter pw = null;
    try {

    new Thread(() -> {
    try {
    String message;
    while ((message = br.readLine()) != null) {
    System.out.println("客户端说" + message);
    System.out.println("服务器请输入：");
    }
    } catch (IOException e) {
    System.out.println("客户端读入失败！");
    }
    }).start();
    Scanner input = new Scanner(System.in);
    while (true) {
    System.out.println(ip + "恭喜你抽中五百万！");
    String say = input.nextLine();
    pw.println("服务器说"+say);
    }
    } catch (NullPointerException e) {
    System.out.println("IO流传入对象，有对象为null，立马核对，建议：查看try块中对象可能赋值为null");
    } finally {
        //输入流的关闭
        if (br!=null)
            try {
                br.close();
            } catch (IOException e) {
                System.out.println("");

            }
        //输出流的关闭
    if (pw != null)
    pw.close();
    if (socket!= null&&!socket.isClosed())
    try {
    socket.close();
    } catch (IOException e) {
    System.out.println("通讯关闭，关闭失败");
    }
    }
    }
    }
    }

